package com.springboot.learn.retry.repository.db;

import com.springboot.learn.retry.message.RetryMessage;
import com.springboot.learn.retry.model.MyRetryContext;
import com.springboot.learn.retry.model.RetryTargetInfo;
import com.springboot.learn.retry.repository.RetryTaskRepository;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import java.util.Date;
import java.util.List;

/**
 * @author BG343674
 * created by BG343674 on 2019/11/23
 */
@Repository
public class RetryTaskRepositoryDbImpl implements RetryTaskRepository {

    @Autowired
    private RetryMessage retryMessage;
    @Autowired
    private RetryMapper retryMapper;


    @Override
    public boolean taskExist(String sign) {
        return retryMapper.taskExist(sign);
    }

    @Override
    public MyRetryContext get(Object key) {
        Example uuid1 = Example.builder(Retry.class).where(
                Sqls.custom().andEqualTo("uuid", key)
        ).build();
        List<Retry> retries = retryMapper.selectByExample(uuid1);
        if (retries == null || retries.isEmpty()) {
            return null;
        }
        return new MyRetryContext();
    }

    @Override
    public void save(MyRetryContext value) {
        Retry retry = new Retry();
        retry.setRetryCount(value.getRetryCount());
        RetryTargetInfo retryTargetInfo = value.getRetryTargetInfo();
        RetryTargetInfo.RetryTargetInfoJsonParser retryTargetInfoJsonParser = RetryTargetInfo.RetryTargetInfoJsonParser.parse(retryTargetInfo);
        retry.setClassName(retryTargetInfoJsonParser.getClassName());
        retry.setMethodName(retryTargetInfoJsonParser.getMethodName());
        retry.setArgsType(retryTargetInfoJsonParser.getArgsType());
        retry.setArgs(retryTargetInfoJsonParser.getArgs());
        retry.setSign(retryTargetInfoJsonParser.sign());
        retry.setRetryTime(new Date(value.getTime()));
        retry.setStartTime(new Date());
        retry.setStatus(1);
        retry.setUuid(value.getUuid());
        retryMapper.insertSelective(retry);
        // 发送通知
        retryMessage.consumeAt(value, value.getTime());
    }

    @Override
    public void updateStatus(MyRetryContext retryContext) {
        Example uuid1 = Example.builder(Retry.class).where(
                Sqls.custom().andEqualTo("uuid", retryContext.getUuid())
        ).build();
        Retry update = new Retry();
        Integer status = retryContext.getStatus();
        update.setStatus(status);
        update.setMessage(ExceptionUtils.getRootCauseMessage(retryContext.getException()));
        update.setRetryCount(retryContext.getRetryCount());
        update.setRetryTime(new Date(retryContext.getTime()));
        retryMapper.updateByExampleSelective(update, uuid1);
        // 成功 达到重试次数上限不再重试
        if (status != 3 && status != 4) {
            retryMessage.consumeAt(retryContext, retryContext.getTime());
        }
    }
}
